﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text; 
using Newtonsoft.Json;
using T.ServiceComponent.Database.Service;
using T.FAS.Runtime.DataModel.Dao;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataModel.Dao
{
    /// <summary>
    /// 元数据验证接口
    /// </summary>
    public class DatabaseValidator
    {
        public const string MetaDataType = "Database";
        public const string MetaDataTypeCN = "数据库元数据";
        public bool CreateMetadata(Database database)
        {
            var Assert = GetEntityValidateResult(database);
            Assert.FailIfErrorResult();
            return Assert.GetAssertResult().Result;
        }

        public bool DeleteMetadata(string databaseID)
        {
            FASAssert Assert = new FASAssert();
            Assert.IsNotNull(databaseID, $"数据库删除时未指定MetaDataID");
            Assert.FailIfErrorResult();
            return Assert.GetAssertResult().Result;
        }

        public bool GetMetadata(Database database)
        {
            var Assert = GetEntityValidateResult(database, CRUDType.Retrive);
            Assert.FailIfErrorResult();
            return Assert.GetAssertResult().Result;
        }

        public bool UpdateMetadata(Database database)
        {
            //因为目前更新采用先删后加的方式，所以采用相同校验规则
            return CreateMetadata(database);
        }

        public bool GetMetadataRTP(Database database)
        {
            //目前运行时获取元数据跟设计时一致
            return GetMetadata(database);
        }

        private FASAssert GetEntityValidateResult(Database database, CRUDType crudType = CRUDType.Create)
        {
            FASAssert Assert = new FASAssert();
            Assert.IsNotNull(database, $"请检查Database参数");
            Assert.FailIfErrorResult(); //如果为空引用直接抛出异常
            var unifyCode = $"元数据Code:{database.Code},ID:{database.ID}";

            /***********通用系统字段校验**********/
            Assert.IsNotNull(database.Creator, $"{unifyCode}的系统字段:{nameof(database.Creator)}不能为空!\r\n");
            Assert.IsNotNull(database.CreateTime, $"{unifyCode}的系统字段:{nameof(database.CreateTime)}不能为空!\r\n");
            Assert.IsNotNull(database.LastModifier, $"{unifyCode}的系统字段:{nameof(database.LastModifier)}不能为空!\r\n");
            Assert.IsNotNull(database.LastModifyTime, $"{unifyCode}的系统字段:{nameof(database.LastModifyTime)}不能为空!\r\n");

            if (crudType == CRUDType.Create)
            {
                var MetaDataInfo = database;
                //租户ID验证
                Assert.IsNotNull(MetaDataInfo.TenantID, $"{unifyCode}的系统字段:{nameof(MetaDataInfo.TenantID)}不能为空!\r\n");

                /***********统一元数据管理DB个性化校验**********/
                Assert.IsNotNull(MetaDataInfo.AppID, $"{unifyCode}的系统字段:{nameof(MetaDataInfo.AppID)}不能为空!\r\n");
                Assert.IsNotNull(MetaDataInfo.ModuleID, $"{unifyCode}的系统字段:{nameof(MetaDataInfo.ModuleID)}不能为空!\r\n");
            }
            /*********************业务校验***********************/
            Assert.IsTrue(Enum.TryParse(database.DbType, false, out DatabaseType dBType), $"{unifyCode}的{nameof(database.DbType)}的数据库类型:{database.DbType}不符合要求!\r\n");

            /*********************配置项Check***********************/
            Assert.IsTrue(database.DatabaseConfigs != null && database.DatabaseConfigs.Count > 0, $"{unifyCode}的数据库配置项不能为空！\r\n", true);
            var defaultCfg = database.DatabaseConfigs.Where(cfg => cfg.IsDefault).ToList();
            Assert.IsTrue(defaultCfg.Count == 1, $"{unifyCode}的数据库配置项只能有一个默认配置！\r\n", true);
            Assert.IsTrue(defaultCfg[0].Mode == 1, $"{unifyCode}的数据库默认配置必须是读写类型！\r\n", true);
            Assert.IsTrue(database.DatabaseConfigs.All(cfg => !string.IsNullOrEmpty(cfg.ConfigKey)), $"{unifyCode}的数据库配置项集合中包含ConfigKey为空的配置项！\r\n");
            //关闭数据库配置项【说明】字段必填限制
            //Assert.IsTrue(Meta.DatabaseConfigs.All(cfg => !string.IsNullOrEmpty(cfg.ConfigName)), $"{unifyCode}的数据库配置项集合中包含ConfigName为空的配置项！\r\n");
            
            /**********获取时加入的额外控制***********/
            if(crudType == CRUDType.Retrive)
            {
                Assert.IsNotNull(database.ID, $"{unifyCode}的系统字段:{nameof(database.ID)}不能为空!\r\n");
                Assert.IsNotNull(database.Name, $"{unifyCode}的系统字段:{nameof(database.Name)}不能为空!\r\n");
                Assert.IsNotNull(database.Code, $"{unifyCode}的系统字段:{nameof(database.Code)}不能为空!\r\n");
                Assert.IsTrue(database.DatabaseConfigs.All(cfg => !string.IsNullOrEmpty(cfg.DatabaseID)), $"{unifyCode}的数据库配置项集合中包含DatabaseID为空的配置项！\r\n");

            }

            return Assert;
        }
    }
}
